#pragma once

#include "MysqlResult.h"
#include <vector>

namespace mysql {

    class MysqlPreparedStatement {

    public:

        // 构造函数，初始化 MySQL 连接和预处理语句对象
        MysqlPreparedStatement(MYSQL *conn, const std::string &sql);

        // 析构函数，释放预处理语句对象
        ~MysqlPreparedStatement() { mysql_stmt_close(stmt_); }

        /**
          * @brief  设置整数参数
          * @note   参数不要直接传入字面量，会引发未定义的错误
          * @param  parameter 参数的索引位置
          * @param  value     整形参数的引用
          */
        void setInt(int parameter, int &value);

        /**
          * @brief  设置字符串参数
          * @note   参数不要直接传入字面量，会引发未定义的错误
          * @param  parameter 参数的索引位置
          * @param  value     字符串参数
          */
        void setString(int parameter, const std::string &value);

        /**
          * @brief  执行非查询语句
          * @retval 非查询语句返回结果
          */
        bool execute();

        /**
          * @brief  执行查询语句并返回结果集对象
          * @retval 结果集对象
          */
        MysqlResult executeQuery();

        /**
          * @brief  获取受影响的行数
          * @retval 受影响的行数
          */
        unsigned long getUpdateCount() const { return mysql_stmt_affected_rows(stmt_); }

    private:

        /**
          * @brief  进行参数绑定
          * @note   execute和executeQuery会自动调用该接口，请勿重复调用
          */
        void bindParameters();

        // MySQL 连接对象
        MYSQL *conn_;

        // 预处理语句对象
        MYSQL_STMT *stmt_;

        // 参数绑定信息
        std::vector<MYSQL_BIND> bind_;

    };

}
